﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Windows;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;

namespace SNSComponent.SNSProvider
{
    public abstract class BaseOAuth2Provider : BaseProvider
    {
        protected string AppKey { get; private set; }

        protected string AppSecret { get; private set; }

        protected Uri RedirectUri { get; private set; }

        public BaseOAuth2Provider(string appKey, string appSecret, Uri redirectUri ,string providerName)
            :base(providerName)
        {
            AppKey = appKey;
            AppSecret = appSecret;
            RedirectUri = redirectUri;
            
        }

        Uri _authUri;
        public override void GetToken()
        {
            _authUri = GetAuthUri();
            OpenAuthPage();

        }

        PhoneApplicationFrame _frame;
        AuthPage _authPage;

        private void OpenAuthPage()
        {
          
            if (null == _frame)
            {
                // Hook up to necessary events and navigate
                _frame = Application.Current.RootVisual as PhoneApplicationFrame;
                if (null != _frame)
                {
                    _frame.Navigated += OnFrameNavigated;
                    _frame.NavigationStopped += OnFrameNavigationStoppedOrFailed;
                    _frame.NavigationFailed += OnFrameNavigationStoppedOrFailed;

                    _frame.Navigate(new Uri("/SNSComponent.WP8;component/AuthPage.xaml",UriKind.Relative));
                }
            }
        }

        private async void OnFrameNavigated(object sender, NavigationEventArgs e)
        {
            AuthPage temp = e.Content as AuthPage;
            if (_authPage == null && temp !=null)
            {
                _authPage = temp;
                _authPage.UserAuth +=OnUserAuthing;
                _authPage.SetAuthUri(_authUri);
                
            }
            if (temp == null)
            {
                _frame.Navigated -= OnFrameNavigated;
                _frame.NavigationStopped -= OnFrameNavigationStoppedOrFailed;
                _frame.NavigationFailed -= OnFrameNavigationStoppedOrFailed;
                _frame = null;
                if (_authPage != null)
                {
                    Uri uri = _authPage.VerifierUri;
                    _authPage.UserAuth -= OnUserAuthing;
                    _authPage = null;
                    if (uri == default(Uri))
                    {
                        _authPage = null;
                        OnTokenComplated( new ResultData(this,ResultState.UserCanceled));
                    }
                    else
                    {
                            ResultData result = await GetAccessToken(uri);
                            if (result.ResultState == ResultState.Success)
                            {
                                OnTokenChanged();
                                OnTokenComplated(result);
                            }
                            else
                            {
                                OnTokenComplated(result);
                            }
                    }
                   

                }
                else
                {
                    OnTokenComplated(new ResultData(this,ResultState.UserCanceled));

                }

            }
           
        }

        private void OnFrameNavigationStoppedOrFailed(object sender, EventArgs e)
        {
            if (_authPage != null)
            {
                _authPage.UserAuth -= OnUserAuthing;
            }
            _frame.Navigated -= OnFrameNavigated;
            _frame.NavigationStopped -= OnFrameNavigationStoppedOrFailed;
            _frame.NavigationFailed -= OnFrameNavigationStoppedOrFailed;
            _frame = null;
            _authPage = null;
            OnTokenComplated(new ResultData(this,ResultState.UserCanceled));
        }

        protected abstract void OnUserAuthing(object sender, UserAuthEventArgs e);

        protected abstract Uri GetAuthUri();

        protected abstract Task<ResultData> GetAccessToken(Uri verifyUri);

     
        
    }
}
